#include<iostream>
using namespace std;
#include<pthread.h>
#include<vector>
#include<unistd.h>
#include<string.h>
#define NUM 5  //创建多个执行流， NUM为执行流个数

using namespace std;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

int* p = nullptr;
__thread int g_val = 0;
__thread int number;

//线程的数据信息。 
struct threadData
{
public:
    threadData(int number, pthread_mutex_t* mutex)
    {
        threadname = "thread-" + to_string(number);
        lock = mutex;
    }

public:
    string threadname;
    pthread_mutex_t* lock;
};


int tickets = 1000;
void* getTicket(void* args)
{
    threadData* td = static_cast<threadData*>(args);
    const char* name = td->threadname.c_str();

    while (true)
    {
        pthread_mutex_lock(td->lock); //加锁, 申请锁成功才能往后执行， 否则阻塞等待。
        pthread_mutex_lock(td->lock); //加锁, 申请锁成功才能往后执行， 否则阻塞等待。

        if (tickets > 0)
        {
            usleep(1000);
            printf("who=%s, get a ticket: %d\n", name, tickets);
            tickets--;
            pthread_mutex_unlock(td->lock); 
        }
        else 
        {
            pthread_mutex_unlock(td->lock); 
            break;
        } 
        usleep(13);
    }
    return nullptr;
}


int main()
{   
    pthread_mutex_init(&lock, nullptr);

    vector<pthread_t> tids;
    vector<threadData*> thread_datas;
    //我们创建多个执行流， 为了能够验证每个线程都有一个独立的栈结构

    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        threadData* td = new threadData(i, &lock);
        thread_datas.push_back(td); 
        pthread_create(&tid, nullptr, getTicket, td);
        tids.push_back(tid);
    }

    for (auto e : tids)
    {
        pthread_join(e, nullptr);
    }
    

    // pthread_mutex_destroy(&lock);
    return 0;
}


// #include<iostream>
// #include<cstdio>
// #include<cstring>
// #include<vector>
// #include<unistd.h>
// #include<pthread.h>
// #include<string>
// using namespace std;

// int tickets = 1000;
// #define NUM 4
// class threadData
// {
// public:
//     threadData(int number)
//     {
//         threadname = "thread-" + to_string(number);
//     }
//     string threadname;
// };

// void* GetTicket(void* args)
// {
//     threadData* td = static_cast<threadData*>(args);
//     while(true)
//     {
//         if (tickets > 0)
//         {
//             usleep(1000);
//             cout << td->threadname << " get a tickets: " << tickets << endl;
//             tickets--;
//         }
//         else break;
//     }

//     cout << "quit " << endl;
    

//     return nullptr;    
// }
// int main()
// {
//     vector<pthread_t> tids;
//     vector<threadData*>thread_datas;
//     for (int i = 1; i <= NUM; i++)
//     {
//         pthread_t tid;
//         threadData* td = new threadData(i);
//         pthread_create(&tid, nullptr, GetTicket, td);
//         tids.push_back(tid);
//     }

//     for (auto e : tids)
//     {
//         pthread_join(e, nullptr);
//     }

//     for (auto td : thread_datas)
//     {
//         delete td;
//     }

//     return 0;
// }


// #include<iostream>
// using namespace std;
// #include<pthread.h>
// #include<vector>
// #include<unistd.h>
// #include<string.h>
// #include"LockGuard.h"

// #define NUM 5  //创建多个执行流， NUM为执行流个数

// using namespace std;
// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// int* p = nullptr;
// //线程的数据信息。 
// struct threadData
// {
// public:
//     threadData(int number, pthread_mutex_t* mutex)
//     {
//         threadname = "thread-" + to_string(number);
//         lock = mutex;
//     }

// public:
//     string threadname;
//     pthread_mutex_t* lock;
// };


// int tickets = 1000;
// void* getTicket(void* args)
// {
//     threadData* td = static_cast<threadData*>(args);
//     const char* name = td->threadname.c_str();

//     while (true)
//     {
//         {
//             LockGuard lockguard(&lock); //定义临时的lockguard对象。 RAII风格的锁
//             if (tickets > 0)
//             {
//                 usleep(1000);
//                 printf("who=%s, get a ticket: %d\n", name, tickets);
//                 tickets--;
//             }
//             else 
//             {
//                 break;
//             } 
//         }
//         usleep(13);
//     }
//     return nullptr;
// }


// int main()
// {   
//     pthread_mutex_init(&lock, nullptr);

//     vector<pthread_t> tids;
//     vector<threadData*> thread_datas;
//     //我们创建多个执行流， 为了能够验证每个线程都有一个独立的栈结构

//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_t tid;
//         threadData* td = new threadData(i, &lock);
//         thread_datas.push_back(td); 
//         pthread_create(&tid, nullptr, getTicket, td);
//         tids.push_back(tid);
//     }

//     for (auto e : tids)
//     {
//         pthread_join(e, nullptr);
//     }
    

//     // pthread_mutex_destroy(&lock);
//     return 0;
// }


